<%def name="WriteValue_real(value)"> \
    %if isinstance(value , list):
{\
    %for single_val in value:
${WriteValue_real(single_val)},\
    %endfor
}\
    %elif isinstance(value , tuple):
{\
    %for single_val in value:
[${single_val[0]}] = ${WriteValue_real(single_val[1])},\
    %endfor
}\
    %else:
<%
    if isinstance(value , bool):
        value = str(value)
    elif isinstance(value , str):
        value = "\"" + value + "\""
    else:
        value = value
%>\
${value}\
    %endif
</%def>\
using System;
using System.IO;
using System.Collections.Generic;
namespace Generated.Config
{
    public partial class ${TableName}DataMap
    {
        private static ${TableName}DataMap _instance;
        private static List<${TableName}> _configListCache;
        private static System.Action _loadedAction = null;

        public static void Init(Action<string, Action<Stream>> loadDataFunc, Action loaded = null)
        {
            loadDataFunc("${TableName}", OnLoadedData);
            _loadedAction = loaded;
        }

        private static void OnLoadedData(Stream data){
            _instance = Parser.ParseFrom(data);
            if(_loadedAction != null)
            {
                _loadedAction.Invoke();
                _loadedAction = null;
            }
        }

        public static void DeInit()
        {
            _instance = null;
            _configListCache = null;
            _loadedAction = null;
        }

        public static ${TableName} GetConfigByKey(${ValueNormalTypeList[0]} key)
        {
            ${TableName} ret;
            _instance.Configs.TryGetValue(key, out ret);
            return ret;
        }

        public static List<${TableName}> GetAll()
        {
            if (_configListCache != null)
            {
                return _configListCache;
            }
            _configListCache = new List<${TableName}>(_instance.Configs.Count);
            var values = _instance.Configs.Values;
            foreach (var item in values)
            {
                _configListCache.Add(item);
            }
            return _configListCache;
        }

%if len(IndexKeyDict) > 0:
    % for column, val_dict in IndexKeyDict.items():
         %if val_dict['multiple']:
        private static Dictionary<${ValueNormalTypeList[column]}, List<${TableName}>> ${ValueNameList[column]}IndexDict = new Dictionary<${ValueNormalTypeList[column]}, List<${TableName}>>(){
            %else:
        private static Dictionary<${ValueNormalTypeList[column]}, ${TableName}> ${ValueNameList[column]}IndexDict = new Dictionary<${ValueNormalTypeList[column]}, ${TableName}>(){
            %endif
        %for key, val in val_dict['values'].items():
<%
    vals = val['vals']
%>\
            %if val['multiple']:
            {${WriteValue_real(key)} , new List<${TableName}>{\
                %for val in vals:
GetConfigByKey(${WriteValue_real(val)}),\
                %endfor
}},
            %else:
            {${WriteValue_real(key)} , GetConfigByKey(${WriteValue_real(vals[0])})},
            %endif
        %endfor
        };
    %if val_dict['multiple']:
        public static List<${TableName}> GetWith${ValueNameList[column]}Index(${ValueNormalTypeList[column]} indexKey){
            List<${TableName}> ret;
            ${ValueNameList[column]}IndexDict.TryGetValue(indexKey, out ret);
            return ret;
        }
    %else:
        public static ${TableName} GetWith${ValueNameList[column]}Index(${ValueNormalTypeList[column]} indexKey){
            ${TableName} ret;
            ${ValueNameList[column]}IndexDict.TryGetValue(indexKey, out ret);
            return ret;
        }
    %endif
    % endfor
%endif


%if len(PrimaryValueList) > 0:
        private static Dictionary<int, ${TableName}> ${TableName}PrimaryKeyDict = new Dictionary<int, ${TableName}>{
            % for row  in range(len(PrimaryValueList)):
            {${PrimaryValueList[row]} , GetConfigByKey(${ValueList[row][0]})},
            % endfor
        };


        <%
            PrimaryParms = 'int ' + PrimaryNameList[0]
            for index in range(1,len(PrimaryNameList)):
                PrimaryParms =  PrimaryParms + ',' + 'int ' +  PrimaryNameList[index]
        %>

        private static int[] lenArray = new int[]{\
<% index = 0 %>\
        % for column in PrimaryIndexList:
<% primaryKeyLen = pow(10,PrimaryLenDict[column]) %>\
${primaryKeyLen},\
<% index = index + 1 %>\
            %endfor
};

        public static ${TableName} GetConfigByPrimaryKey(${PrimaryParms}){
            var primaryKey = ${PrimaryNameList[0]} * lenArray[1]\
            % for index in range(1,len(PrimaryNameList)):
        + ${PrimaryNameList[index]} * lenArray[${index + 1}]\
            % endfor
;
            return GetConfigByKey(primaryKey);
        }
        %endif

    }
}